//-----------------------------------------------------------------------
// <copyright file="StartStopWebSiteTest.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// </copyright>
// <author>Simon Bell</author>
// <email>v-sibell</email>
// <date>2004-06-02</date>
// <summary>Tests starting, stopping and pausing a web site</summary>
//-----------------------------------------------------------------------

namespace Microsoft.Sdc.Tasks.Test
{
    using System;
    using System.Globalization;
    using System.IO;
    using System.Text;
    using System.Net;

    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using Microsoft.Sdc.Tasks.Configuration;
    using Microsoft.Sdc.Tasks;
    using Microsoft.Build.Framework;
    using Microsoft.Sdc.Tasks.Configuration.Web;

    /// <summary>
    /// Unit test for starting, stopping and pausing web sites
    /// </summary>
    [TestClass]
    public class StartStopWebSiteTest
    {


        private string m_webFullPath;

        public StartStopWebSiteTest()
        {
        }

        [TestMethod]
        public void TestWebSiteStopStartTasks()
        {
            //Create a temporary web site and get its ID
            string hostName = "UnitTest";
            string port = "90";
            string tempWebSiteName = CreateTempWebSite(hostName, port);
            int id = Microsoft.Sdc.Tasks.Configuration.Web.WebSite.GetIdentifierFromDescription("localhost", tempWebSiteName);

            //Add a virtual directory (with a "Hello World" .htm file) to this web site
            string virtualDirectoryFolder = TaskTestUtilities.CreateTempFolder();
            string testHtmlFile = "HelloWorld.htm";

            try
            {
                //Create a new file
                System.IO.FileStream testFile = System.IO.File.Create(virtualDirectoryFolder + "\\" + testHtmlFile);
                Byte[] info = new UTF8Encoding(true).GetBytes(GetTestHtml());
                testFile.Write(info, 0, info.Length);
                testFile.Close();

                string virtualDirectoryName = AddVirtualDirectory(tempWebSiteName, virtualDirectoryFolder, id);

                //Add a binding
                AddBinding(hostName, tempWebSiteName, Convert.ToString(id, CultureInfo.InvariantCulture), "157.58.35.233", "91");

                //Start the web site
                StartWebSite(tempWebSiteName);

                //We should now be able to access the following uri
                string uri = "http://" + hostName + ":" + port + "/" + virtualDirectoryName + "/" + testHtmlFile;

                //Pause the web site
                PauseWebSite(tempWebSiteName);

                //Pause the web site
                ContinueWebSite(tempWebSiteName);

                //Stop the web site
                StopWebSite(tempWebSiteName);

                //Unload the virtual directory
                UnloadVirtualDirectory(tempWebSiteName, virtualDirectoryName, id);

                DeleteVirtualDirectory(tempWebSiteName, virtualDirectoryName);

                //Delete the website
                DeleteWebSite(tempWebSiteName);
            }
            finally
            {
                //Delete the physical directory (and files)
                if (Directory.Exists(virtualDirectoryFolder))
                {
                    Directory.Delete(virtualDirectoryFolder, true);
                }
                if (Directory.Exists(m_webFullPath))
                {
                    Directory.Delete(m_webFullPath, true);
                }
            }

        }

        internal string CreateTempWebSite(string hostName, string port)
        {
            Tasks.Web.WebSite.Create createWebSiteTask = new Tasks.Web.WebSite.Create();
            
            //Generate a new random webname
            Guid guid = Guid.NewGuid();
            string webname = guid.ToString();
            webname = webname.Replace("-", "").Substring(0, 11);
            string newFolder = webname;

            if (WebSite.Exists("localhost", webname))
            {
                Assert.Fail("WebSite already existed");
            }

            m_webFullPath = Environment.ExpandEnvironmentVariables(@"%TEMP%\" + newFolder);

            if (Directory.Exists(m_webFullPath))
            {
                Assert.Fail("WebSite path already exists");
            }

            Directory.CreateDirectory(m_webFullPath);

            if (!(Directory.Exists(m_webFullPath)))
            {
                Assert.Fail("WebSite path not created");
            }

            createWebSiteTask.Description = webname;
            createWebSiteTask.Path = m_webFullPath;
            createWebSiteTask.HostName = hostName;
            createWebSiteTask.Port = port;
            bool createWebSiteTaskReturnValue = createWebSiteTask.Execute();
            Assert.IsTrue(createWebSiteTaskReturnValue);

            //Check the web now exists
            bool exists = WebSite.Exists("localhost", webname);
            Assert.IsTrue(exists);

            return createWebSiteTask.Description;
        }

        private void StartWebSite(string webSiteName)
        {
            Tasks.Web.WebSite.Start startWebSiteTask = new Tasks.Web.WebSite.Start();
            startWebSiteTask.Description = webSiteName;

            bool startWebSiteTaskReturnValue = startWebSiteTask.Execute();
            Assert.IsTrue(startWebSiteTaskReturnValue);
            Assert.IsTrue(startWebSiteTask.Description == webSiteName);
        }

        private void PauseWebSite(string webSiteName)
        {
            //Pause the web site
            Tasks.Web.WebSite.Pause pauseWebSiteTask = new Tasks.Web.WebSite.Pause();
            pauseWebSiteTask.Description = webSiteName;

            bool pauseWebSiteTaskReturnValue = pauseWebSiteTask.Execute();
            Assert.IsTrue(pauseWebSiteTaskReturnValue);
            Assert.IsTrue(pauseWebSiteTask.Description == webSiteName);
        }

        private void ContinueWebSite(string webSiteName)
        {
            //Continue web site
            Tasks.Web.WebSite.Continue continueWebSiteTask = new Tasks.Web.WebSite.Continue();
            continueWebSiteTask.Description = webSiteName;

            bool continueWebSiteTaskReturnValue = continueWebSiteTask.Execute();
            Assert.IsTrue(continueWebSiteTaskReturnValue);
            Assert.IsTrue(continueWebSiteTask.Description == webSiteName);
        }

        private void StopWebSite(string webSiteName)
        {
            Tasks.Web.WebSite.Stop stopWebSiteTask = new Tasks.Web.WebSite.Stop();
            stopWebSiteTask.Description = webSiteName;

            bool stopWebSiteTaskReturnValue = stopWebSiteTask.Execute();
            Assert.IsTrue(stopWebSiteTaskReturnValue);
            Assert.IsTrue(stopWebSiteTask.Description == webSiteName);
        }

        internal void DeleteWebSite(string webSiteName)
        {
            Tasks.Web.WebSite.DeleteWebsite deleteWebSiteTask = new Tasks.Web.WebSite.DeleteWebsite();
            deleteWebSiteTask.Description = webSiteName;

            bool deleteWebSiteTaskReturnValue = deleteWebSiteTask.Execute();
            Assert.IsTrue(deleteWebSiteTaskReturnValue);
            Assert.IsTrue(deleteWebSiteTask.Description == webSiteName);

            bool exists = WebSite.Exists("localhost", webSiteName);
            Assert.IsFalse(exists);
        }

        private string GetTestHtml()
        {
            StringBuilder htmlBuilder = new StringBuilder();
            System.IO.StringWriter writer = new System.IO.StringWriter(htmlBuilder, CultureInfo.InvariantCulture);
            writer.Write(@"<HTML><HEAD></HEAD><BODY><B>Hello World</B></BODY></HTML>");
            return writer.ToString();

        }

        internal string AddVirtualDirectory(string webSiteName, string virtualDirectoryFolder, int id)
        {
            string virtualDirectoryName = TaskTestUtilities.GenerateNewGuid().Replace("-", "");

            //Create a virtual directory
            Tasks.Web.WebSite.CreateVirtualDirectory createdVirtualDirectory = new Tasks.Web.WebSite.CreateVirtualDirectory();
            createdVirtualDirectory.Path = virtualDirectoryFolder;
            createdVirtualDirectory.VirtualDirectoryName = virtualDirectoryName;
            createdVirtualDirectory.WebSiteName = webSiteName;

            //Attempt to create it with a task
            bool createVirtualDirectorySuccess = createdVirtualDirectory.Execute();
            Assert.IsTrue(createVirtualDirectorySuccess);

            //Ensure it exists
            Assert.IsTrue(VirtualDirectory.Exists(createdVirtualDirectory.VirtualDirectoryName, id, "localhost"));

            //Check properties
            Assert.IsTrue(createdVirtualDirectory.Path == virtualDirectoryFolder);
            Assert.IsTrue(createdVirtualDirectory.VirtualDirectoryName == virtualDirectoryName);

            return virtualDirectoryName;
        }

        private void UnloadVirtualDirectory(string webSiteName, string virtualDirectoryName, int id)
        {
            //Create a virtual directory
            Tasks.Web.WebSite.UnloadVirtualDirectory unloadVirtualDirectory = new Tasks.Web.WebSite.UnloadVirtualDirectory();
            unloadVirtualDirectory.VirtualDirectoryName = virtualDirectoryName;
            unloadVirtualDirectory.WebSiteName = webSiteName;

            //Attempt to create it with a task
            bool unloadVirtualDirectorySuccess = unloadVirtualDirectory.Execute();
            Assert.IsTrue(unloadVirtualDirectorySuccess);

            //Check properties
            Assert.IsTrue(unloadVirtualDirectory.VirtualDirectoryName == virtualDirectoryName);
        }

        internal void DeleteVirtualDirectory(string webSiteName, string virtualDirectoryName)
        {
            //Create a virtual directory
            Tasks.Web.WebSite.DeleteVirtualDirectory deleteVirtualDirectory = new Tasks.Web.WebSite.DeleteVirtualDirectory();
            deleteVirtualDirectory.VirtualDirectoryName = virtualDirectoryName;
            deleteVirtualDirectory.WebSiteName = webSiteName;

            //Attempt to create it with a task
            bool deleteVirtualDirectorySuccess = deleteVirtualDirectory.Execute();
            Assert.IsTrue(deleteVirtualDirectorySuccess);

            //Check properties
            Assert.IsTrue(deleteVirtualDirectory.VirtualDirectoryName == virtualDirectoryName);
            Assert.IsTrue(deleteVirtualDirectory.WebSiteName == webSiteName);

        }

        private void AddBinding(string hostName, string webSiteName, string id, string ipAddress, string port)
        {
            Tasks.Web.WebSite.AddBinding addBindingTask = new Tasks.Web.WebSite.AddBinding();
            addBindingTask.Identifier = id;
            addBindingTask.IPAddress = ipAddress;
            addBindingTask.Port = port;
            addBindingTask.HostName = hostName;
            addBindingTask.Description = webSiteName;

            //Attempt to create binding with a task
            //bool addBindingTaskReturnValue = addBindingTask.Execute();
            //Assert.IsTrue("AddBindingTask", addBindingTaskReturnValue);

            Assert.IsTrue(addBindingTask.Identifier == id);
            Assert.IsTrue(addBindingTask.IPAddress == ipAddress);
            Assert.IsTrue(addBindingTask.Port == port);
        }

        private void MakeWebRequest(string uri, bool expectSuccess)
        {
            HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri);
            try
            {
                HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
                Console.WriteLine("Response: " + webResponse.StatusDescription);
            }
            catch (Exception e)
            {
                if (expectSuccess)
                {
                    Console.WriteLine("Failed to access " + uri + ": " + e.ToString());
                    Assert.Fail("Received web response when should have failed");
                }
                else
                {
                    Console.WriteLine("Failed to access " + uri + ": " + e.ToString());
                    return;
                }
            }
        }
    }
}


